#ifndef __BUFFER_H__
#define __BUFFER_H__
#include <iostream>
#include <vector>
#include <string>
#include <cassert>

using std::vector;
using std::string;

class Buffer {
public:
    static const size_t kCheapPrepend = 8;
    static const size_t kInitialSize = 1024;

    Buffer(size_t initialSize = kInitialSize)
        : _buffer(initialSize), _readIndex(kCheapPrepend), _writeIndex(kCheapPrepend) {}

    size_t readableBytes() const
    {
        return _writeIndex - _readIndex;
    }

    size_t writableBytes() const
    {
        return _buffer.size() - _writeIndex;
    }

    void swap(Buffer &rhs)
    {
        _buffer.swap(rhs._buffer);
        std::swap(_readIndex, rhs._readIndex);
        std::swap(_writeIndex, rhs._writeIndex);
    }
    void append(const string &str)
    {
        append(str.data(), str.size());
    }
    void append(const char *data, size_t len)
    {
        if (writableBytes() < len)
        {
            // 扩展缓冲区
            _buffer.resize(_buffer.size() + len);
        }
        std::copy(data, data + len, _buffer.data() + _writeIndex);
        _writeIndex += len;
    }

    const char *peek() const
    {
        return _buffer.data() + _readIndex;
    }

    void retrieve(size_t len) // 从读索引移动 len 字节
    {
        assert(len <= readableBytes());
        if (len <= readableBytes()) // 如果读索引和写索引相等，重置
        {
            _readIndex += len;
        }
        else
        {
            retrieveAll();
        }
    }

    void retrieveAll()
    {
        _readIndex = kCheapPrepend;
        _writeIndex = kCheapPrepend;
    }

private:
    vector<char> _buffer;
    size_t _readIndex;  // 读索引
    size_t _writeIndex; // 写索引
};

#endif